﻿/**	@file		critical_section.h
 *	@date		(2005-11-01 00:05:54)/(2011-04-27 22:46:29)
 *-----------------------------------------------------------------------------
 *	\brief		临界区对象.
 *	@version	1.0.16.20
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/


#if			!defined(__LOLIX__LOLI__CRITICAL_SECTION__K_IN_G__)
#define		__LOLIX__LOLI__CRITICAL_SECTION__K_IN_G__

#if			defined(__cplusplus)

#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)

#if			!defined(__LOLIX__TOY__TIME_TYPES__K_IN_G__)
	#include	"../toy/time_types.h"
#endif	//	!defined(__LOLIX__TOY__TIME_TYPES__K_IN_G__)

#if			!defined(__LOLIX__TOY__L_X_ASSERT_NICK__K_IN_G__)
	#include	"../toy/lx_assert.h"
#endif	//	!defined(__LOLIX__TOY__L_X_ASSERT_NICK__K_IN_G__)

namespace lolix{namespace loli{
	class critical_section;
	class critical_section_factory;
}}


class LOLIX_NO_VTABLE lolix::loli::critical_section_factory
	: public lolix::itf
{
	LOLIX_DECLARE_ITF(lolix::loli::critical_section_factory, lolix::itf, (0xf4ec27c2, 0xa479d93e, 0x4edcbffa, 0xf5920d39));
public:
	LOLIX_INTERFACE(create_inst, LOLIX_RETNV, (critical_section** out_ptr));
	LOLIX_INTERFACE(create_inst, LOLIX_RETNV, (critical_section** out_ptr, const wchar_t* name));
};


class LOLIX_NO_VTABLE lolix::loli::critical_section
	: public lolix::itf
{
public:
	LOLIX_DECLARE_ITF(lolix::loli::critical_section, lolix::itf, (0x3e7c6d19, 0xa45646cf, 0x90ab74ee, 0xdb320e91));
	LOLIX_INTERFACE(enter		, LOLIX_RETNV,	(void));
	LOLIX_INTERFACE(leave		, LOLIX_RETNV,	(void));
	LOLIX_INTERFACE(try_enter	, LOLIX_RETNV,	(bool* const is_enter));

	LOLIX_INLINE_CALL LOLIX_RETNV safe_enter(void){ return this?this->enter():LOLIX_RETNV_OK;}
	LOLIX_INLINE_CALL LOLIX_RETNV safe_leave(void){ return this?this->leave():LOLIX_RETNV_OK;}
	LOLIX_INLINE_CALL LOLIX_RETNV safe_try_enter(bool* const is_enter){if ( !this ) { *is_enter = true; return lolix::LOLIX_RETNV_OK; } return this->try_enter(is_enter); }
};

namespace lolix{namespace loli{
	typedef critical_section_factory cs_factory;
}}

#endif	//	defined(__cplusplus)
#endif	//	!defined(__LOLIX__LOLI__CRITICAL_SECTION__K_IN_G__)
